#include <vector>
#include <fstream>

#include "headers/PPUSystem.h"
#include "headers/Windows.h"
#include "headers/FileLoader.h"

extern WindowsMenager cWindowsMenager;
extern FileLoader cFileLoader;

void PPUSystem::Init() {
    TableBackground.resize(0x100);
    TableSprites.resize(0x100);
    
    for (int i=0; i<0x100; i++) {
        TableBackground[i].resize(0x10);
        TableSprites[i].resize(0x10);
    }
    
    Palette.resize(0x20);
}


void PPUSystem::SetColorInPalette(int index, int color) {
    Palette[index] = color;
}

void PPUSystem::SetPalette(const int* colors) {
    for (int i=0; i<0x20; i++) {
        Palette[i] = colors[i];
    }
}

void PPUSystem::SetPattern(int pattern_type, int index, char* pattern) {
    
    switch (pattern_type) {
        case BACKGROUND:
            for (int i=0; i<0x10; i++)
                TableBackground[index][i] = pattern[i];
            break;
        case SPRITES:
            for (int i=0; i<0x10; i++)
                TableSprites[index][i] = pattern[i];
            break;
    }
        
}


void PPUSystem::DrawPattern(int pattern_type, unsigned char pattern, int attributes, const char* DrawObjectName, int x, int y) {

    int color;
    int pal_adr = 0;
    
    attributes <<= 2;
    
    std::vector<std::vector<char> >* Table = &TableBackground;
    if (pattern_type == SPRITES) {
        Table = &TableSprites;
        pal_adr = 16;
    }

    for (int i=0; i<8; i++) //wspolrzedna x
        for (int j=0; j<8; j++) { //wspolrzedna y
            //wczytaj pierwszy bit:
            color = ((*Table)[pattern][j]>>i)&1;    
            //wczytaj drugi bit:
            if (i>0) 
                color |= ((*Table)[pattern][j+8]>>(i-1))&2;
            else 
                color |= ((*Table)[pattern][j+8]<<1)&2;
                    
            color &= 3;
                  
            if (!(pattern_type==SPRITES && color==0))            
                cWindowsMenager.DrawPixel(DrawObjectName, GetRGBFromNesColor(Palette[color|attributes + pal_adr]), x+(7-i), y+j);                                   
        }    
}

void PPUSystem::Uncompress(int pattern_type, int src, int dest, int lenght) {
    
    char* patterns = new char[lenght * 0x10]; //Buffer for patterns
    cFileLoader.Uncompress(patterns, src, lenght); //Uncompress all patterns
           
    char pattern[0x10]; //temporary pattern
        
    /* Add all patterns to PPUSysytem */
    for (int i=0, num=0; num < lenght; i+=0x10, num++) {
        for (int j=0; j<0x10; j++) {
            pattern[j] = patterns[i+j];
        }
        SetPattern(pattern_type, num + (unsigned char)dest, pattern);
    }
       
    delete [] patterns; /* Delete buffer */
    
}

